最常在Tailwind的範例中看到它,支援Vue3、React兩大框架。(Vue只支援3)
特點1:純功能UI不帶有樣式
特點2:支援無障礙功能
npm install @headlessui/vue
在需要使用的組件中import就好
假設今天要做一個在父組件頁面打開子組件Modal視窗的效果
首先在父組件先引入需要用到的組件
import { Dialog, DialogPanel, TransitionRoot, TransitionChild } from '@headlessui/vue';
import pluginModel from '../components/plugnModel.vue';
// 這是要打開的子組件
避免瀏覽器跳警告我會在components中註冊他們
export default {
components: {
pluginModel, // 子組件
Dialog, // 功能本體(開關在這,如果要全畫面暗掉的背景也放這)
DialogPanel, // 視窗本人放這
DialogTitle, // 告訴用戶的無障礙標題
DialogDescription, // 告訴用戶的無障礙內容
TransitionRoot, // 整個頁面的過渡動畫效果
TransitionChild, // 單個組件的過渡動畫(須在TransitionRoot內使用)
}
}
官方文件沒有動畫效果的範例可以參考✿這裡
但實際上不可能不加過渡的吧(吧?)
雖然說 Vue 中有內建的 Transition 效果
但他可以控制更細微的子組件動畫
所以讓我們加上上面提到的 TransitionRoot & TransitionChild
// 父組件
<template>
// 使用動畫需要將原本在Dialog的open開關改到TransitionRoot :show="isOpen"
// 注意是 :show 不是 :open
<TransitionRoot :show="isOpen" as="template"
enter="duration-300 ease" enter-from="opacity-0" enter-to="opacity-100"
leave="duration-200 ease-in" leave-from="opacity-100" leave-to="opacity-0">
<Dialog class="relative z-30" as="div" @close="closeModal"> // 注意這邊是@close
<!-- Modal背景 -->
<TransitionChild as="template"
enter="ease-out duration-300" enter-from="opacity-0" enter-to="opacity-100"
leave="ease-in duration-200" leave-from="opacity-100" leave-to="opacity-0">
// 直接點擊背景可以關閉視窗
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"
aria-hidden="true" @click="closeModal" />
</TransitionChild>
<!-- Modal內容 -->
<div class="fixed inset-0 overflow-y-auto">
<div class="flex min-h-full items-center justify-center p-4 text-center">
<!-- 上面兩行負責定位 -->
<TransitionChild as="template"
enter="ease-out duration-500 transform"
enter-from="opacity-0 -translate-y-40 sm:scale-95"
enter-to="opacity-100 -translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leave-from="opacity-100 sm:scale-100"
leave-to="opacity-0 sm:scale-95">
<DialogPanel
class="fixed top-20 h-5/6 overflow-y-auto w-11/12 bg-white rounded-lg md:w-8/12">
<!-- 子組件 -->
</DialogPanel>
</TransitionChild>
</div>
</div>
</Dialog>
</TransitionRoot>
</template>
上面會用到的資料、函式
export default {
setup() {
// 控制 Modal 開關
let isOpen = ref(false);
// 關閉 Modal
function closeModal() {
isOpen.value = false;
}
return {
isOpen,
closeModal,
}
},
components: {
Dialog,
DialogPanel,
TransitionRoot,
TransitionChild,
},
}
子組件就包含DialogTitle
與DialogDescription
完成!
官方說明文件很完整,但實作的時候常常漏東漏西
所以在這邊紀錄一下流程跟需要注意的地方